/*
 * Copyright (c) 2022 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef HIVIEWDFX_HILOG_H
#define HIVIEWDFX_HILOG_H
/**
 * @addtogroup HiLog
 * @{
 * 
 * @brief Provides logging functions.
 * 
 * For example, you can use logging functions to output logs of the specified log type, service domain, log tag, and log level.
 *
 * @syscap SystemCapability.HiviewDFX.HiLog
 *
 * @since 8
 */

/**
 * @file log.h
 * 
 * @brief Defines the logging functions of the HiLog module.
 *
 * Before outputting logs, you must define the service domain, and log tag, use the function with the specified log type and level, 
 * and specify the privacy identifier. \n
 * Service domain: service domain of logs. You can define the value as required. Its value is a hexadecimal integer ranging from 0x0 to 0xFFFF. \n
 * Log tag: a string used to identify the class, file, or service behavior. \n
 * Log level: DEBUG, INFO, WARN, ERROR, or FATAL \n
 * Parameter format: printf format string, which starts with a % character, including a parameter type identifier and a variable parameter. \n
 * Privacy identifier: <b>{public}</b> or <b>{private}</b> added between the % character and the parameter type identifier in each parameter. 
 * If no privacy identifier is added, the parameter is considered to be <b>private</b>. \n
 *
 * Sample code:\n
 * Defining the service domain and log tag:\n
 *     #define LOG_DOMAIN 0x0201\n
 *     #define LOG_TAG "MY_TAG"\n
 * Outputting logs:\n
 *     HILOG_WARN({@link LOG_APP}, "Failed to visit %{private}s, reason:%{public}d.", url, errno);\n
 * Output: \n
 *     05-06 15:01:06.870 1051 1051 W 0201/MY_TAG: Failed to visit <private>, reason:503.\n
 * 
 * @since 8
 */
#include <stdarg.h>
#include <stdbool.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @brief Defines the service domain for a log file.
 *
 * The service domain is used to identify the subsystem and module of a service. Its value is a hexadecimal integer ranging from 0x0 to 0xFFFF. 
 * If the value is beyond the range, its significant bits are automatically truncated. \n
 * 
 * @since 8
 */
#ifndef LOG_DOMAIN
#define LOG_DOMAIN 0
#endif

/**
 * @brief Defines a string constant used to identify the class, file, or service.
 *
 * @since 8
 */
#ifndef LOG_TAG
#define LOG_TAG NULL
#endif

/**
 * @brief Enumerates log types.
 *
 * Currently, only {@link LOG_APP} is available. \n
 * 
 * @since 8
 */
enum LogType
{
      /** Application log */
      LOG_APP = 0,  
}; 

/**
 * @brief Enumerates log levels.
 *
 * You are advised to select log levels based on their respective use cases: \n
 * DEBUG: provides more detailed process information than INFO logs to help developers analyze service processes and locate faults. 
 * DEBUG logs are not recorded in official versions by default. They are available in debug versions or in official versions with the debug function enabled. \n
 * INFO: indicates the key service process nodes and exceptions (for example, no network signal or login failure) that occur during service running. 
 * These logs should be recorded by the dominant module in the service to avoid repeated logging conducted by multiple invoked modules or low-level functions. \n
 * WARN: indicates a severe, unexpected fault that has little impact on users and can be rectified by the programs themselves or through simple operations. \n
 * ERROR: indicates a program or functional error that affects the normal running or use of the functionality and can be fixed at a high cost, for example, 
 * by resetting data. \n
 * FATAL: indicates that a program or functionality is about to crash and the fault cannot be rectified. \n
 * 
 * @since 8
 */
enum LogLevel            
{
      /** DEBUG level to be used by OH_LOG_DEBUG */
      LOG_DEBUG = 3,  
      /** INFO level to be used by OH_LOG_INFO */
      LOG_INFO = 4, 
      /** WARN level to be used by OH_LOG_WARN */
      LOG_WARN = 5, 
      /** ERROR level to be used by OH_LOG_ERROR */
      LOG_ERROR = 6, 
      /** FATAL level to be used by OH_LOG_FATAL */
      LOG_FATAL = 7, 
}; 

/**
 * @brief Outputs logs.
 *
 * You can use this function to output logs based on the specified log type, log level, service domain, log tag, and variable parameters 
 * determined by the format specifier and privacy identifier in the printf format.
 * 
 * @param type Indicates the log type. The type for third-party applications is defined by {@link LOG_APP}.
 * @param level Indicates the log level, which can be <b>LOG_DEBUG</b>, <b>LOG_INFO</b>, <b>LOG_WARN</b>, <b>LOG_ERROR</b>, and <b>LOG_FATAL</b>.
 * @param domain Indicates the service domain. Its value is a hexadecimal integer ranging from 0x0 to 0xFFFF.
 * @param tag Indicates the log tag, which is a string used to identify the class, file, or service.
 * @param fmt Indicates the format string, which is an enhancement of a printf format string and supports the privacy identifier. 
 * Specifically, <b>{public}</b> or <b>{private}</b> is added between the % character and the format specifier in each parameter.
 * @param ... Indicates the parameter list corresponding to the parameter type in the format string. 
 * The number and type of parameters must be mapped onto the identifier in the format string.
 * @return Returns <b>0</b> or a larger value if the operation is successful; returns a value smaller than <b>0</b> otherwise.
 *
 * @since 8
 */
int OH_LOG_Print(LogType type, LogLevel level, unsigned int domain, const char *tag, const char *fmt, ...)
    __attribute__((__format__(os_log, 5, 6)));

/**
 * @brief Checks whether logs of the specified service domain, log tag, and log level can be output.
 * 
 * @param domain Indicates the service domain of logs.
 * @param tag Indicates the log tag.
 * @param level Indicates the log level.
 * @return Returns <b>true</b> if the specified logs can be output; returns <b>false</b> otherwise.
 *
 * @since 8
 */
bool OH_LOG_IsLoggable(unsigned int domain, const char *tag, LogLevel level);

/**
 * @brief Outputs DEBUG logs. This is a function-like macro.
 *
 * Before calling this function, define the log service domain and log tag. Generally, you need to define them at the beginning of the source file. \n
 * 
 * @param type Indicates the log type. The type for third-party applications is defined by {@link LOG_APP}.
 * @param fmt Indicates the format string, which is an enhancement of a printf format string and supports the privacy identifier. 
 * Specifically, <b>{public}</b> or <b>{private}</b> is added between the % character and the format specifier in each parameter.
 * @param ... Indicates the parameter list corresponding to the parameter type in the format string. 
 * The number and type of parameters must be mapped onto the identifier in the format string.
 * @see OH_LOG_Print 
 *
 * @since 8
 */
#define OH_LOG_DEBUG(type, ...) ((void)OH_LOG_Print((type), LOG_DEBUG, LOG_DOMAIN, LOG_TAG, __VA_ARGS__))

/**
 * @brief Outputs INFO logs. This is a function-like macro.
 *
 * Before calling this function, define the log service domain and log tag. Generally, you need to define them at the beginning of the source file. \n
 * 
 * @param type Indicates the log type. The type for third-party applications is defined by {@link LOG_APP}.
 * @param fmt Indicates the format string, which is an enhancement of a printf format string and supports the privacy identifier. 
 * Specifically, <b>{public}</b> or <b>{private}</b> is added between the % character and the format specifier in each parameter.
 * @param ... Indicates the parameter list corresponding to the parameter type in the format string. 
 * The number and type of parameters must be mapped onto the identifier in the format string.
 * @see OH_LOG_Print 
 *
 * @since 8
 */
#define OH_LOG_INFO(type, ...) ((void)OH_LOG_Print((type), LOG_INFO, LOG_DOMAIN, LOG_TAG, __VA_ARGS__))

/**
 * @brief Outputs WARN logs. This is a function-like macro.
 *
 * Before calling this function, define the log service domain and log tag. Generally, you need to define them at the beginning of the source file.
 * 
 * @param type Indicates the log type. The type for third-party applications is defined by {@link LOG_APP}.
 * @param fmt Indicates the format string, which is an enhancement of a printf format string and supports the privacy identifier. 
 * Specifically, <b>{public}</b> or <b>{private}</b> is added between the % character and the format specifier in each parameter.
 * @param ... Indicates the parameter list corresponding to the parameter type in the format string. 
 * The number and type of parameters must be mapped onto the identifier in the format string.
 * @see OH_LOG_Print 
 *
 * @since 8
 */
#define OH_LOG_WARN(type, ...) ((void)OH_LOG_Print((type), LOG_WARN, LOG_DOMAIN, LOG_TAG, __VA_ARGS__))

/**
 * @brief Outputs ERROR logs. This is a function-like macro.
 *
 * Before calling this function, define the log service domain and log tag. Generally, you need to define them at the beginning of the source file.
 * 
 * @param type Indicates the log type. The type for third-party applications is defined by {@link LOG_APP}.
 * @param fmt Indicates the format string, which is an enhancement of a printf format string and supports the privacy identifier. 
 * Specifically, <b>{public}</b> or <b>{private}</b> is added between the % character and the format specifier in each parameter.
 * @param ... Indicates the parameter list corresponding to the parameter type in the format string. 
 * The number and type of parameters must be mapped onto the identifier in the format string.
 * @see OH_LOG_Print
 *
 * @since 8
 */
#define OH_LOG_ERROR(type, ...) ((void)OH_LOG_Print((type), LOG_ERROR, LOG_DOMAIN, LOG_TAG, __VA_ARGS__))

/**
 * @brief Outputs FATAL logs. This is a function-like macro.
 *
 * Before calling this function, define the log service domain and log tag. Generally, you need to define them at the beginning of the source file. \n
 * 
 * @param type Indicates the log type. The type for third-party applications is defined by {@link LOG_APP}.
 * @param fmt Indicates the format string, which is an enhancement of a printf format string and supports the privacy identifier. 
 * Specifically, <b>{public}</b> or <b>{private}</b> is added between the % character and the format specifier in each parameter.
 * @param ... Indicates the parameter list corresponding to the parameter type in the format string. 
 * The number and type of parameters must be mapped onto the identifier in the format string.
 * @see OH_LOG_Print
 *
 * @since 8
 */
#define OH_LOG_FATAL(type, ...) ((void)HiLogPrint((type), LOG_FATAL, LOG_DOMAIN, LOG_TAG, __VA_ARGS__))

#ifdef __cplusplus
}
#endif
/** @} */
#endif  // HIVIEWDFX_HILOG_H
